home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1985-1992 New York University
- *
- * This file is part of the Ada/Ed-C system. See the Ada/Ed README file for
- * warranty (none) and distribution info and also the GNU General Public
- * License for more details.
-
- */
- /* chapter 12, part b */
-
- #include "hdr.h"
- #include "vars.h"
- #include "libprots.h"
- #include "librprots.h"
- #include "miscprots.h"
- #include "smiscprots.h"
- #include "dclmapprots.h"
- #include "sspansprots.h"
- #include "errmsgprots.h"
- #include "nodesprots.h"
- #include "setprots.h"
- #include "chapprots.h"
-
- static void update_one_entry(Symbol, Symbol, Symbolmap);
- static void update_scalar_signature(Symbol, Symbol);
- static void update_record_entry(Symbol, Symbol, Symbolmap);
- static void update_array_entry(Symbol, Symbol, Symbolmap);
- static Node update_new_node(Node);
- static Symbol update_new_name(Symbolmap, Symbol);
- static void instantiate_derived_types(Node, Symbolmap);
- static Set update_overloads(Set, Symbolmap);
- static int check_recursive_instance(Node);
- static int scan_instance(Node);
- static void nodemap_free(Nodemap);
- static Node nodemap_get(Nodemap, Node);
- static void nodemap_put(Nodemap, Node, Node);
-
- void instantiate_subprog_tree(Node node, Symbolmap type_map)
- /*;instantiate_subprog_tree*/
- {
- /* Build the tree for the instantiated object, and the corresponding
- * symbol table entries, some of which may contain pointers to new tree.
- */
-
- Node id_node, gen_node, b_node, specs_node;
- Symbol prog_name, gen_name, g_p, new_p;
- /* Nodemap node_map; */
- Tuple sig, itup, packs;
- Node stmts_node, decl_node, handler_node;
- Symbolmap rename_map;
- Tuple truly_renamed;
- Fortup ft1;
-
- id_node = N_AST1(node);
- gen_node = N_AST2(node);
- prog_name = N_UNQ(id_node);
- gen_name = N_UNQ(gen_node);
- /* instantiate all entities local to the subprogram. The type map is aug-
- * mented with the mapping of local generic entities into their instances
- */
-
- itup = instantiate_symbtab(gen_name, prog_name, type_map);
- rename_map = (Symbolmap) itup[1];
- packs = (Tuple)itup[2];
- truly_renamed = (Tuple) itup[3];
- /* Now use this mapping to instantiate the AST itself. */
- node_map = nodemap_new(); /* global object. */
- current_node = node;
-
- sig = SIGNATURE(gen_name);
- b_node = (Node) sig[3];
-
- retrieve_generic_tree(b_node, (Node)0); /* if in another file. */
- /* Instantiate body and transform into subprogram node*/
- specs_node = N_AST1(b_node);
- decl_node = N_AST2(b_node);
- stmts_node = N_AST3(b_node);
- handler_node = N_AST4(b_node);
-
- N_KIND(node) = as_subprogram;
- N_AST1(node) = instantiate_tree(specs_node, rename_map);
- N_AST2(node) = instantiate_tree(decl_node, rename_map);
- N_AST3(node) = instantiate_tree(stmts_node, rename_map);
- N_AST4(node) = instantiate_tree(handler_node, rename_map);
- /* Finally, complete the instantiation of the symbol table. The later
- * happens after tree instantiation, to insure that symbtab instances
- * point to the instantiated nodes. The entry for the instance has been
- * constructed by chain_overloads, and is not updated further.
- */
- truly_renamed = tup_with(truly_renamed, (char *) gen_name);
- update_symbtab_nodes(rename_map, truly_renamed);
-
- /* Update the private declarations of enclosed packages */
- FORTUP(g_p=(Symbol), packs, ft1);
- new_p = symbolmap_get(rename_map, g_p);
- private_decls(new_p) = (Set) update_private_decls(g_p, rename_map);
- ENDFORTUP(ft1);
- instantiate_derived_types(decl_node, rename_map);
-
- /*TBSL: should we free old node_map??? ds 7nov */
- nodemap_free(node_map); /* free current allocation */
- node_map = nodemap_new(); /* discard after use. */
- }
-
- void instantiate_pack_tree(Node node, Symbolmap type_map,
- Tuple instance_list) /*;instantiate_pack_tree*/
- {
- /* Build tree for instantiated object, and symbol table entries for all
- * its local entities. In the case of a forward instantiation, visibility
- * rules require that the symbol table of the visible part be fully
- * instantiated. The expander then instantiates the symbol table for the
- * body, together with the corresponding tree.
- */
- Node id_node, gen_node;
- Symbol package, gen_name, g_p, new_p, new_f, sym, gen_formal, over;
- /* Nodemap node_map; */
- Tuple sig;
- Node priv_node, decl_node, b_node, spec_node, new_decl_node;
- Node new_priv_node;
- Node new_b_node;
- Symbolmap rename_map;
- Tuple ltup, itup, truly_renamed;
- Tuple packs, gen_tup, gen_list;
- Fortup ft1, ft2;
- Forset fs1, fs2;
- Set overloadables;
- id_node = N_AST1(node);
- gen_node = N_AST2(node);
- package = N_UNQ(id_node);
- gen_name = N_UNQ(gen_node);
-
- /* Instantiate all entities local to the package. */
- itup = instantiate_symbtab(gen_name, package, type_map);
- rename_map = (Symbolmap)itup[1];
- packs = (Tuple)itup[2];
- truly_renamed = (Tuple) itup[3];
- tup_free(itup); /* itup just used to pass result*/
- /* Now instantiate the AST itself, and complete the instantiation of the
- * symbol table.
- */
- node_map = nodemap_new(); /* global object.*/
- current_node = node;
- sig = SIGNATURE(gen_name);
- decl_node = (Node) sig[2];
- priv_node = (Node) sig[3];
- retrieve_generic_tree(decl_node, priv_node);
- b_node = (Node) sig[4];
- spec_node = node_new(as_package_spec);
- new_decl_node = instantiate_tree(decl_node, rename_map);
- new_priv_node = instantiate_tree(priv_node, rename_map);
- /* N_LIST(new_decl_node) = instance_list + N_LIST(new_decl_node); */
- N_LIST(new_decl_node) = tup_add(instance_list, N_LIST(new_decl_node));
- N_AST1(spec_node) = id_node;
- N_AST2(spec_node) = new_decl_node;
- N_AST3(spec_node) = new_priv_node;
- if (b_node != OPT_NODE) { /* Instantiate body as well */
- retrieve_generic_tree(b_node, (Node)0);
- new_b_node = instantiate_tree(b_node, rename_map);
- N_KIND(new_b_node) = as_package_body;
- }
- else {
- new_b_node = copy_node(node);
- /* Attach tpe_map to node for eventual code emission */
- ltup = tup_new(2);
- ltup[1] = (char *) rename_map;
- ltup[2] = (char *) needs_body(gen_name);
- N_AST4(new_b_node) = new_instance_node(ltup);
- }
- /* In any case, emit the spec node before the body */
- make_insert_node(node, tup_new1((char *) spec_node), new_b_node);
-
- /* Node references in the symbol table must point to the instantiated
- * tree.
- */
- update_symbtab_nodes(rename_map, truly_renamed);
-
- /* Complete construction of visibility information for inner packages. */
- FORTUP(g_p=(Symbol), packs, ft1);
- new_p = symbolmap_get(rename_map, g_p);
- /* construct visible map for it, so that the proper instantiated
- * entities within new package become accessible.
- */
- /* TBSL: review translation of next line */
- /*
- * visible(new_p) := { [id, symbolmap_get(rename_map, old_n) ? old_n] :
- * [id, old_n] in visible(g_p)};
- */
-
- /*
- * Nested packages (which are not generic) are now visible: their
- * local entities are nameable using qualified names.
- */
- if (NATURE(g_p) != na_generic_package
- && NATURE(g_p) != na_generic_package_spec) {
- vis_mods = tup_with(vis_mods, (char *) new_p);
- }
- /*
- *The top level package is added to vis_mods in end_specs, called
- * at the end of package_instance.
- */
- /* Finally, apply renamings to the private declarations. */
- private_decls(new_p) = (Set) update_private_decls(g_p, rename_map);
- ENDFORTUP(ft1);
-
- instantiate_derived_types(decl_node, rename_map);
- /* The instantiation does not include a copy of the generic part. RM 12.3(5)
- * Thus, the instantiation of the generic parameters themselves, is not
- * visible. If, however, a generic subprogram parameter has an overload in
- * the visible part of the package, that overload itself must remain
- * accessible; so we just remove the name of the instantiated generic
- * subprogram parameter from its own overloads set.
- */
- overloadables = set_new(0);
- gen_list = (Tuple) SIGNATURE(gen_name)[1];
- FORTUP(gen_tup = (Tuple), gen_list, ft2);
- gen_formal = (Symbol) gen_tup[1];
- new_f = symbolmap_get(rename_map, gen_formal);
- if (new_f == (Symbol) 0) /* error in instantiation */
- /* TBSL: can we just return here ? */
- continue;
- if (NATURE(gen_formal)==na_procedure || NATURE(gen_formal)==na_function)
- overloadables = set_with(overloadables, (char *) new_f);
- ENDFORTUP(ft2);
-
- FORSET(sym=(Symbol), overloadables, fs1);
- FORSET(over = (Symbol), overloadables, fs2);
- if (set_mem((char *) over, OVERLOADS(sym)))
- OVERLOADS(sym) = set_del(OVERLOADS(sym), (char *) over);
- ENDFORSET(fs2);
- ENDFORSET(fs1);
- }
-
- Tuple instantiate_symbtab(Symbol gen_name, Symbol new_n, Symbolmap rename_map)
- /*;instantiate_symbtab*/
- {
- /* This procedure constructs the symbol table for instantiated units.
- * This involves the instantiation of local entities. Constructing their
- * symbol table entries is akin to assigning "locations" for them. Such
- * locations also have to be created for instantiated 'in' parameters.
- * but not for types, or inout parameters, which are simply renamings.
- * On the other hand, generic subprogram parameters are already defined as
- * renamings and the instantiation provides the name of the entity which
- * they actually rename. Finally, thediscriminants of generic
- * private types are mapped into the discriminants of the actuals by
- * renaming also, and are not otherwise instantiated.
- * The mapping rename_map is expanded by this procedure, and used at the
- * point of call to complete instantiation of the bodies.
- */
-
- Tuple gen_list, rtup;
- Symbol n;
- Tuple renamed_params, packs;
- Symbol gen_d;
- Tuple instantiated_scopes;
- Symbol g_n;
- Symbol new_pn;
- Declaredmap old_decls, new_decls;
- char *id;
- Symbol old_n;
- int nat;
- Fordeclared fd1;
- Tuple workpile, tup;
- Forsymbol fsym;
- Fortup ft1;
-
-
- tup = SIGNATURE(gen_name);
- gen_list= (Tuple) tup[1];
-
- /*renamed_params := { n : [n, -] in gen_list | NATURE(n) != na_in} +
- * {gen_d : [gen_d, -] in rename_map | nature(gen_d) = na_discriminant};
- */
- renamed_params = tup_new1((char *) new_n);
- FORTUP(tup=(Tuple), gen_list, ft1);
- n = (Symbol) tup[1];
- nat = NATURE(n);
- if (nat != na_in && nat != na_procedure && nat != na_function) {
- if (!tup_mem((char *) n, renamed_params))
- renamed_params = tup_with(renamed_params, (char *) n);
- }
- ENDFORTUP(ft1);
- FORSYMBOL(gen_d, n, rename_map, fsym);
- nat = NATURE(gen_d);
- if (nat == na_discriminant) {
- if (!tup_mem( (char *) gen_d, renamed_params))
- renamed_params = tup_with(renamed_params, (char *) gen_d);
- }
- else if (nat == na_in || nat == na_function || nat == na_procedure) {
- /* set scope of instantiated parameters to the instantiated unit */
- SCOPE_OF(n) = new_n;
- }
- ENDFORSYMBOL(fsym);
- /* Create the proper prefix for the unique names of instantiated entities */
- #ifdef TBSN
- o_pref :
- = prefix;
- prefix :
- = original_name(new_n) + '.';
- #endif
- /* An additional complication has to do with nested declarations(records,
- * other packages) within the generic object. For these we must also
- * create instances of their symbol tables, so that type checking of
- * their uses can be performed. We therefore traverse recursively all
- * nested declarations within the generic object, to collect every object
- * whose symbol table field must be instantiated. This may be done at
- * generic definition time, and will be more efficient than here. For
- * procedures and functions, only their signature is needed to perform
- * type-checking, but their symbol tables are instantiated as well, for
- * completeness and for use by the code generator.
- */
-
- packs = tup_new(0); /* to collect names of nested packages. */
- instantiated_scopes = tup_new(0); /* All of which have declared maps.*/
- tup = tup_new(2);
- tup[1] = (char *) gen_name;
- tup[2] = (char *) new_n;
- workpile = tup_new1((char *) tup);
- while (tup_size(workpile)) {
- tup = (Tuple) tup_frome(workpile);
- g_n = (Symbol) tup[1];
- new_pn = (Symbol) tup[2];
- tup_free(tup);
- if (!tup_mem((char *) g_n, instantiated_scopes)) {
- instantiated_scopes =tup_with(instantiated_scopes, (char *) g_n);
- }
- if (cdebug2 > 3) TO_ERRFILE("Instantiating scope " );
-
- /* Iterate over all items declared in g_n, the generic object (or any
- * object nested within and which has declarations : package, record,
- * subprogram, task) and collect declarations for instantiated items.
- */
-
- old_decls = DECLARED(g_n);
- new_decls = dcl_new(0);
-
- FORDECLARED(id, old_n, old_decls, fd1);
- if (cdebug2 > 0) TO_ERRFILE(" Instantiating item ");
-
- if (tup_mem((char *)old_n, renamed_params)){
- /*
- * generic parameter which was renamed already.
- */
- n = symbolmap_get(rename_map, old_n);
- if (n != (Symbol)0)
- /* will be Symbol 0 ONLY if there was an error, in which
- * case we do not put it in the declared map !
- */
- dcl_put_vis(new_decls, id, n, IS_VISIBLE(fd1));
- if (REPR(n) != (Tuple)0) {
- REPR(old_n) = REPR(n);
- }
- }
- else if ((new_n = symbolmap_get(rename_map, old_n)) != (Symbol)0)
- /* id renames an object which has been instantiated already.
- * The instantiation of id will point to the instantiation of
- * that object.
- */
- dcl_put_vis(new_decls, id, new_n, IS_VISIBLE(fd1));
- else if (SCOPE_OF(old_n) != g_n) {
- /* old_n is a renaming of some other entity, generic or other-
- * wise, which is defined in some outer scope. The instantia-
- * tion of old_n must rename the same entity.
- */
- if ((new_n = symbolmap_get(rename_map, old_n)) == (Symbol)0){
- symbolmap_put(rename_map, old_n, old_n);
- new_n = old_n;
- /*new_n = rename_map(old_n) := old_n;*/
- }
- if (!tup_mem((char *) old_n, renamed_params))
- renamed_params = tup_with(renamed_params, (char *) old_n);
- dcl_put_vis(new_decls, id, new_n, IS_VISIBLE(fd1));
- }
- else if (NATURE(old_n) != na_void) {
- new_n = sym_new(na_void);
- /* map generic to actual. */
- symbolmap_put(rename_map, old_n, new_n);
- /* Create entry in declared for instantiated item. Other symb
- * table fields are set in update_symbtab_info below.
- */
- NATURE(new_n) = NATURE(old_n);
- SCOPE_OF(new_n) = new_pn;
- if (REPR(old_n) != (Tuple)0) {
- REPR(new_n) = tup_copy(REPR(old_n));
- }
- dcl_put_vis(new_decls, id, new_n, IS_VISIBLE(fd1));
- if (SCOPE_OF(old_n) != old_n
- && DECLARED(old_n) != (Declaredmap)0
- /* an anonymous task type has a declared map, which is
- * instantiated when the corresponding single task object
- * is. That map should not be instantiated twice.
- */
- && !is_anonymous_task(old_n)){
- /* Nested record, package, subprogram, or task.
- * Put on workpile with appropriate prefix for new names.
- */
- tup = tup_new(2);
- tup[1] = (char *) old_n;
- tup[2] = (char *) new_n;
- workpile = tup_with(workpile, (char *) tup);
- }
- }
- ENDFORDECLARED(fd1);
-
- /* Assign new declarations to package, record or task entity. */
-
- DECLARED(new_pn) = new_decls;
- nat = NATURE(g_n);
-
- if (nat == na_package || nat == na_package_spec
- || nat == na_generic_package
- || nat == na_generic_package_spec){
- if (!tup_mem((char *) g_n, packs))
- packs = tup_with(packs , (char *) g_n);
- }
- }
-
- #ifdef TBSN
- prefix = o_pref;
- $ Restore naming environment
- #endif
- rtup = tup_new(3);
- rtup[1] = (char *) rename_map;
- rtup[2] = (char *) packs;
- rtup[3] = (char *) renamed_params;
- return rtup;
- }
-
- void update_symbtab_nodes(Symbolmap rename_map, Tuple truly_renamed)
- /*;update_symbtab_nodes*/
- {
- /*
- * The rename_map contains the generic items and the names of their
- * instantiations. We must now complete the symbol table entries for
- * the later, to insure that type information is correct.
- *
- * Entities that are true renamings (generic types, inout parameters, or
- * actual renamings within the generic object) have no symbol table
- * entry in it, and are skipped in what follows.
- */
-
- Symbol old_n, new_n;
- Forsymbol fsym;
-
- FORSYMBOL(old_n, new_n, rename_map, fsym);
- if (!tup_mem((char *)old_n, truly_renamed) && TYPE_OF(new_n)==(Symbol)0)
- update_one_entry(old_n, new_n, rename_map);
- ENDFORSYMBOL(fsym);
- }
-
- static void update_one_entry(Symbol old_n, Symbol new_n, Symbolmap rename_map)
- /*;update_one_entry*/
- {
- /* Update the symbol table entry of one entity in an instantiated unit.
- * The scope of the new entry has already been established. The node_map
- * (global) takes generic nodes into their instances.
- */
-
- int nat, ii, nn;
- Tuple tup, gen_list, form_list, new_gen_list, new_form_list, otup, ntup;
- Node body_node, decl_node, opt_priv_node, node, n, d;
- Fortup ft1;
- Tuple discr_map, newdiscr_map, newsig, constrain_list, new_constrain_list;
-
- /* SETL macros new_node and new_name are done using procedures
- * update_new_node and update_new_name, respectively.
- */
- TYPE_OF(new_n) = update_new_name(rename_map, TYPE_OF(old_n));
- if (ALIAS(old_n) == symbol_discrete_type)
- /* not in the rename map ! */
- ALIAS(new_n) = root_type(TYPE_OF(new_n));
- else
- ALIAS(new_n) = update_new_name(rename_map, ALIAS(old_n));
-
- ORIG_NAME(new_n) = ORIG_NAME(old_n);
- /* The signature of entities may contain tree nodes (constraints,
- * initial values, etc). The instantiated entries must point to the
- * corresponding instantiated node.
- */
- switch (nat = NATURE(old_n)) {
- case na_constant:
- case na_discriminant:
- case na_in:
- case na_obj:
- d = (Node) default_expr(old_n);
- if (d != (Node)0) {
- if (nat == na_in)
- /* default expression is not attached to generic tree, and
- * must be instantiated separately.
- */
- default_expr(new_n) = (Tuple)instantiate_tree(d, rename_map);
- else
- default_expr(new_n) = (Tuple)update_new_node(d);
- }
- break;
- case na_out:
- case na_inout:
- default_expr(new_n) = (Tuple)OPT_NODE;
- break;
- case na_type:
- if (is_scalar_type(old_n))
- update_scalar_signature(old_n, new_n);
- else if (in_incp_types(TYPE_OF(root_type(old_n)) )) {
- update_record_entry(old_n, new_n, rename_map);
- misc_type_attributes(new_n) = misc_type_attributes(old_n);
- }
- break;
- case na_subtype:
- if (is_scalar_type(old_n))
- update_scalar_signature(old_n, new_n);
- else if (is_array(old_n))
- update_array_entry(old_n, new_n, rename_map);
- else if (is_record(old_n)) {
- tup = SIGNATURE(old_n);
- discr_map = (Tuple) numeric_constraint_discr(tup);
- newsig = tup_new(2);
- numeric_constraint_kind(newsig) = (char *) CONSTRAINT_DISCR;
- nn = tup_size(discr_map);
- newdiscr_map = tup_new(nn);
- for (ii = 1; ii <= nn; ii+=2) {
- newdiscr_map[ii] = (char *) update_new_name(rename_map,
- (Symbol) discr_map[ii]);
- newdiscr_map[ii+1] =
- (char *) update_new_node((Node)discr_map[ii+1]);
- }
- numeric_constraint_discr(newsig) = (char *) newdiscr_map;
- SIGNATURE(new_n) = newsig;
- #ifdef TBSL
- -- status of this is undecided
- misc_type_attributes(new_n) = misc_type_attributes(old_n);
- #endif
- }
- else if (is_access(old_n)) {
- newsig = constraint_new(CONSTRAINT_ACCESS);
- newsig[2] =
- (char *)update_new_name(rename_map, designated_type(old_n));
- SIGNATURE(new_n) = newsig;
- }
- break;
- case na_enum:
- update_scalar_signature(old_n, new_n);
- /*(literal_map(new_n) := {[new_name(l), i]:
- * [l, i] in literal_map(old_n)};
- */
- otup = (Tuple) literal_map(old_n);
- if (otup != (Tuple)0) {
- nn = tup_size(otup);
- ntup = tup_new(nn);
- for (ii = 1; ii <= nn; ii+=2) {
- ntup[ii] = (char *)update_new_name(rename_map,(Symbol)otup[ii]);
- ntup[ii+1] = otup[ii+1];
- }
- }
- else {
- ntup = otup;
- }
- literal_map(new_n) = (Set) ntup;
- break;
- case na_record:
- update_record_entry(old_n, new_n, rename_map);
- break;
- case na_array:
- update_array_entry(old_n, new_n, rename_map);
- break;
- case na_procedure:
- case na_procedure_spec:
- case na_function:
- case na_function_spec:
- case na_literal:
- case na_entry:
- /*signature(new_n) := [new_name(f): f in signature(old_n)];*/
- otup = SIGNATURE(old_n);
- if (otup != (Tuple)0) {
- nn =tup_size(otup);
- ntup = tup_new(nn);
- for (ii = 1; ii <= nn; ii++)
- ntup[ii] = (char *)update_new_name(rename_map,(Symbol)otup[ii]);
- SIGNATURE(new_n) = ntup;
- }
- OVERLOADS(new_n) = update_overloads(OVERLOADS(old_n), rename_map);
- break;
- case na_entry_former:
- case na_entry_family:
- otup = SIGNATURE(old_n);
- if (otup != (Tuple)0) {
- nn = tup_size(otup);
- ntup = tup_new(nn);
- for (ii = 1; ii <= nn; ii++)
- ntup[ii] = (char *)update_new_name(rename_map,(Symbol)otup[ii]);
- SIGNATURE(new_n) = ntup;
- }
- break;
- case na_generic_procedure:
- case na_generic_procedure_spec:
- case na_generic_function:
- case na_generic_function_spec:
- tup = SIGNATURE(old_n);
- gen_list = (Tuple) tup[1];
- form_list = (Tuple) tup[2];
- body_node = (Node) tup[3];
- constrain_list = (Tuple) tup[4];
- /* new_gen_list := [[update_new_name(rename_map, n),
- * update_new_node(node_map, node)]
- * : [n, node] in gen_list];
- */
- nn = tup_size(gen_list);
- new_gen_list = tup_new(nn);
- FORTUPI(tup=(Tuple), gen_list, ii, ft1);
- n = (Node) tup[1];
- node = (Node) tup[2];
- tup =tup_new(2);
- tup[1]= (char *) update_new_name(rename_map, (Symbol) n);
- tup[2] = (char *) update_new_node(node);
- new_gen_list[ii] = (char *) tup;
- ENDFORTUP(ft1);
- /*new_form_list := [replace(n, rename_map): n in form_list];*/
- nn = tup_size(form_list);
- new_form_list = tup_new(nn);
- for (ii = 1; ii <= nn; ii++)
- new_form_list[ii] =
- (char *) replace((Symbol) form_list[ii], rename_map);
- /*new_constrain_list := [replace(n, rename_map): n in constrain_list];*/
- nn = tup_size(constrain_list);
- new_constrain_list = tup_new(nn);
- for (ii = 1; ii <= nn; ii++)
- new_form_list[ii] =
- (char *) replace((Symbol) constrain_list[ii], rename_map);
- tup = tup_new(4);
- tup[1] = (char *) new_gen_list;
- tup[2] = (char *) new_form_list;
- tup[3] = (char *) update_new_node(body_node);
- tup[4] = (char *) new_constrain_list;
- SIGNATURE(new_n) = tup;
- break;
- case na_task_obj:
- case na_task_obj_spec:
- /* declared map (entry names) is shared with anonymous task type.*/
- DECLARED(TYPE_OF(new_n)) = DECLARED(new_n);
- break;
- case na_generic_package:
- case na_generic_package_spec:
- tup = SIGNATURE(old_n);
- gen_list = (Tuple) tup[1];
- decl_node = (Node) tup[2];
- opt_priv_node = (Node) tup[3];
- body_node = (Node) tup[4];
- constrain_list = (Tuple) tup[5];
- /* new_gen_list := [[update_new_name(rename_map, n),
- * update_new_node(node_map, node)]
- * : [n, node] in gen_list];
- */
- nn = tup_size(gen_list);
- new_gen_list = tup_new(nn);
- FORTUPI(tup=(Tuple), gen_list, ii, ft1);
- n = (Node) tup[1];
- node = (Node) tup[2];
- tup =tup_new(2);
- tup[1]= (char *) update_new_name(rename_map, (Symbol) n);
- tup[2] = (char *) update_new_node(node);
- new_gen_list[ii] = (char *) tup;
- ENDFORTUP(ft1);
- /*new_constrain_list := [replace(n, rename_map): n in constrain_list];*/
- nn = tup_size(constrain_list);
- new_constrain_list = tup_new(nn);
- for (ii = 1; ii <= nn; ii++)
- new_form_list[ii] =
- (char *) replace((Symbol) constrain_list[ii], rename_map);
- tup = tup_new(5);
- tup[1] = (char *) new_gen_list;
- tup[2]= (char *) update_new_node(decl_node);
- tup[3] = (char *) update_new_node(opt_priv_node);
- tup[4] = (char *) update_new_node(body_node);
- tup[5] = (char *) new_constrain_list;
- SIGNATURE(new_n) = tup;
- break;
- case na_aggregate:
- OVERLOADS(new_n) = update_overloads(OVERLOADS(old_n), rename_map);
- break;
- case na_access:
- /* update designated type */
- SIGNATURE(new_n) =
- (Tuple) update_new_name(rename_map, designated_type(old_n));
- OVERLOADS(new_n) = update_overloads(OVERLOADS(old_n), rename_map);
- break;
- }
- /* verify all uses of signature and overloads are covered*/
- }
-
- static void update_scalar_signature(Symbol old_n, Symbol new_n)
- /*update_scalar_signature*/
- {
- Tuple otup, ntup;
- Symbol old_base, new_base;
-
- old_base = base_type(old_n);
- new_base = TYPE_OF(new_n);
- otup = SIGNATURE(old_n);
- if (otup != (Tuple)0) {
- ntup = tup_new(tup_size(otup));
- numeric_constraint_kind(ntup) = numeric_constraint_kind(otup);
- numeric_constraint_low(ntup) = (char *) update_new_node
- ((Node)numeric_constraint_low(otup));
- numeric_constraint_high(ntup) = (char *) update_new_node
- ((Node)numeric_constraint_high(otup));
-
- if ((int)numeric_constraint_kind(otup) == CONSTRAINT_DIGITS) {
- if (is_generic_type(old_base)
- && N_KIND((Node)numeric_constraint_digits(otup)) != as_ivalue)
- /* inherit digits from generic actual */
- numeric_constraint_digits(ntup) =
- numeric_constraint_digits(SIGNATURE(new_base));
- else
- numeric_constraint_digits(ntup)=numeric_constraint_digits(otup);
- }
- else if ((int)numeric_constraint_kind(otup) == CONSTRAINT_DELTA) {
- if (is_generic_type(old_base)
- && N_KIND((Node)numeric_constraint_delta(otup)) != as_ivalue) {
- /* inherit generic and small from actual */
- numeric_constraint_delta(ntup) =
- numeric_constraint_delta(SIGNATURE(new_base));
- numeric_constraint_small(ntup) =
- numeric_constraint_small(SIGNATURE(new_base));
- }
- else {
- numeric_constraint_delta(ntup) = numeric_constraint_delta(otup);
- numeric_constraint_small(ntup) = numeric_constraint_small(otup);
- }
- }
- SIGNATURE(new_n) = ntup;
- }
- }
-
- static void update_record_entry(Symbol old_n, Symbol new_n,Symbolmap rename_map)
- /*;update_record_entry*/
- {
- Node i_node , v_node;
- Tuple sig, old_disc_list, new_disc_list;
- int i, disc_size;
-
- sig = record_declarations(new_n) = tup_new(5);
- i_node = (Node) invariant_part(old_n);
- v_node = (Node) variant_part(old_n);
- sig[1] = (char *) update_new_node(i_node); /* invariant_part */
- sig[2] = (char *) update_new_node(v_node); /* variant_part */
- sig[4] = (char *) DECLARED(new_n); /* declared_components */
- old_disc_list = (Tuple) discriminant_list(old_n);
- disc_size = tup_size(old_disc_list);
- new_disc_list = tup_new(disc_size);
- sig[3] = (char *) new_disc_list; /* discriminant_list */
- for (i = 1; i <= disc_size; i++)
- new_disc_list[i] =
- (char *) update_new_name(rename_map, (Symbol)old_disc_list[i]);
- #ifdef TBSL
- misc_type_attributes(new_n) = misc_type_attributes(old_n);
- #endif
- }
-
- static void update_array_entry(Symbol old_n, Symbol new_n, Symbolmap rename_map)
- /*;update_array_entry */
- {
- Tuple newsig, tup;
- Symbol si;
- int i;
- Fortup ft;
-
- /*index_types(new_n) := [new_name(i) : i in index_types(old_n)];*/
- SIGNATURE(new_n) = newsig = tup_new(2);
- tup = tup_new(tup_size(index_types(old_n)));
- FORTUPI(si=(Symbol), (Tuple)index_types(old_n), i, ft);
- tup[i] = (char *) update_new_name(rename_map, si);
- ENDFORTUP(ft);
- newsig[1] = (char *) tup; /* index_types */
- newsig[2] = (char *) update_new_name(rename_map,
- component_type(old_n)); /* component_type */
- #ifdef TBSL
- misc_type_attributes(new_n) = misc_type_attributes(old_n);
- #endif
- }
-
- static Node update_new_node(Node n) /*;update_new_node*/
- {
- /* transcription of macro new_node in update_one_entry */
- Node t;
-
- t = nodemap_get(node_map, n);
- if (t == (Node)0) t = n;
- return t;
- }
-
- static Symbol update_new_name(Symbolmap nmap, Symbol s) /*;update_new_name*/
- {
- /* transcription of macro new_name in update_one_entry */
- Symbol t;
-
- t = symbolmap_get(nmap, s);
- if (t == (Symbol)0) t = s;
- return t;
- }
-
- static void instantiate_derived_types(Node decl_node, Symbolmap rename_map)
- /*;instantiate_derived_types*/
- {
- /* derived type declarations whose parent type is a generic type must be
- * reprocessed, in order to complete the derivation of subprograms from
- * the instance of the generic formal (AI 398).
- */
-
- Symbol gen_p, gen_d, act_p, act_d, act_dt;
- Node n1, n2;
- Fortup ft1;
-
- FORTUP(n1=(Node), N_LIST(decl_node), ft1)
- if (N_KIND(n1) == as_type_decl) n2 = N_AST3(n1);
- else if (N_KIND(n1) == as_subtype_decl) n2 = N_AST2(n1);
- else continue;
-
- if (N_KIND(n2) == as_derived_type) {
- gen_d = N_UNQ(N_AST1(n1)); /* derived type in template */
- gen_p = N_UNQ(N_AST1(N_AST1(n2))); /* parent type in template */
- if (is_generic_type(gen_p) && SCOPE_OF(gen_d) == SCOPE_OF(gen_p))
- {
- act_d = update_new_name(rename_map, gen_d);
- act_p = update_new_name(rename_map, gen_p);
-
- if (NATURE(gen_d) == na_type && NATURE(act_p) == na_subtype) {
- /* if formal has no constraint, but actual is a subtype,
- * must first derive anonymous type, of which the
- * instantiation of the name appearing in the type
- * declaration is a subtype.
- */
- act_dt = sym_new(na_void); /*anonymous derived type */
- dcl_put_vis(DECLARED(scope_name),newat_str(), act_dt, TRUE);
- NATURE(act_d) = na_subtype;
- TYPE_OF(act_d) = act_dt;
- }
- else
- act_dt = base_type(act_d);
- ALIAS(act_d) = ALIAS(act_p);
- SIGNATURE(act_d) = SIGNATURE(act_p);
- SIGNATURE(act_dt) = SIGNATURE(act_p);
- /* For now do not create derived programs. */
- /* build_derived_type(act_p, act_dt, current_node); */
- }
- }
- ENDFORTUP(ft1);
- }
-
- static Set update_overloads(Set oset, Symbolmap rename_map)
- /*;update_overloads*/
- {
- Set nset;
- Forset fs1;
- Symbol si;
-
- nset = (Set)0;
- if (oset != (Set)0) {
- nset = set_new(set_size(oset));
- FORSET(si=(Symbol), oset, fs1);
- nset = set_with(nset, (char *) update_new_name(rename_map, si));
- ENDFORSET(fs1);
- }
- return nset;
- }
-
- Private_declarations update_private_decls(Symbol pack_name,
- Symbolmap rename_map) /*;update_private_decls*/
- {
- /* Complete the instantiation of the private declarations of a package.
- * The same renaming rules apply as for visible symbol table entries.
- * We install each private declaration in the symbol table, update the
- * information, and swap back.
- */
-
- Private_declarations old_decls, new_decls;
- Forprivate_decls fp;
- Symbol old_n, info, new_n, save_new;
-
- new_decls = private_decls_new(0);
- /* TBSL:
- * -- this involves more than swapping, need to copy entries as appropiate
- * -- ds 9 nov 84
- */
-
- /*(forall [old_n, info] in private_decls(pack_name))*/
- old_decls = (Private_declarations) private_decls(pack_name);
- FORPRIVATE_DECLS(old_n, info, old_decls, fp);
- new_n = symbolmap_get(rename_map, old_n);
- if (new_n == (Symbol)0) continue; /* some error. */
-
- #ifdef TBSN
- [save_old, save_new] :
- = [SYMBTABF(old_n), SYMBTABF(new_n)];
- SYMBTABF(old_n) :
- = info;
- #endif
- save_new = sym_new_noseq(na_void);
- sym_copy(save_new, new_n);
- update_one_entry(info, new_n, rename_map);
- NATURE(new_n) = NATURE(info); /* maybe different from visible decl */
- SCOPE_OF(new_n) = symbolmap_get(rename_map, pack_name);
- #ifdef TBSN
- new_decls(new_n) :
- = SYMBTABF(new_n);
- [SYMBTABF(old_n), SYMBTABF(new_n)] :
- = [save_old, save_new];
- #endif
- private_decls_put(new_decls, new_n);
- sym_copy(new_n, save_new);
- ENDFORPRIVATE_DECLS(fp);
- return new_decls;
- }
-
- Node instantiate_tree(Node node, Symbolmap rename_map) /*;instantiate_tree*/
- {
- /*
- * Makes a copy of the tree rooted at node, while replacing occurences
- * of names in domain rename_map by corresponding values. If the
- * instantiation contains an inner forward instantiation, the renaming
- * map of the inner one must be combined with the outer one.
- */
-
- Node root;
- Symbol dnode, rnode;
- Tuple tup, ltup, ntup;
- Symbolmap new_r_map, r_map;
- Forsymbol fsym;
- int i, ni, n;
- unsigned int nkind;
- Node anode, nnode;
- Fortup ft1;
- Symbol old_n, new_n;
-
- if (node == OPT_NODE ) return OPT_NODE;
- nkind = N_KIND(node);
- root = node_new(nkind);
- /*N_VAL(root) = N_VAL(node); very delicate code - 3-20-86 DS */
- if (N_VAL_DEFINED(nkind)) N_VAL (root) = N_VAL (node);
- if (is_terminal_node(nkind) && current_node != OPT_NODE)
- copy_span(current_node, root);
-
- if (nkind == as_function_instance
- || nkind == as_procedure_instance
- || nkind == as_package_instance) {
- /* Update the instantiation information.*/
- tup = tup_copy((Tuple) N_VAL(N_AST4(node)));
- r_map = (Symbolmap) tup[1];
- /* TBSL: should set better size for new_r_map on init. alloc.*/
- /*
- * new_r_map := { [old_n, rename_map(new_n) ? new_n]:
- * [old_n, new_n] in r_map};
- */
- new_r_map = symbolmap_new();
- FORSYMBOL(old_n, new_n, r_map, fsym);
- symbolmap_put(new_r_map, old_n, replace(new_n, rename_map));
- ENDFORSYMBOL(fsym);
- /*N_VAL(root) := [new_r_map, flag]; */
- tup[1] = (char *) new_r_map;
- N_AST4(root) = new_instance_node(tup);
-
- /* And check that no recursive instantiations are implied by
- * the current inner one.
- */
- check_recursive_instance(node);
- }
- /*N_UNQ (root) = symbolmap_get(rename_map, N_UNQ(node)) ? N_UNQ(node);*/
- dnode = N_UNQ(node);
- rnode = symbolmap_get(rename_map, dnode);
- if (rnode == (Symbol)0) rnode = dnode;
- if (nkind == as_array_aggregate || nkind == as_record_aggregate) {
- /* the internally generated name of the aggregate is not in the
- * symbol table, for delicate separate compilation reasons. Each
- * aggregate instance must nevertheless have a distinct name
- */
- rnode = sym_new(na_void);
- }
- if (N_UNQ_DEFINED(N_KIND(root)))
- N_UNQ(root) = rnode;
- /*N_TYPE(root) := symbolmap_get(rename_map, N_TYPE(node)) ? N_TYPE(node);*/
- dnode= N_TYPE(node);
- rnode = symbolmap_get(rename_map, dnode);
- if (rnode == (Symbol)0) rnode = dnode;
- if (N_TYPE_DEFINED(N_KIND(root)))
- N_TYPE(root) = rnode;
- N_SIDE(root) = N_SIDE(node);
- /* N_AST (root) := [instantiate_tree(n, rename_map):
- * n in N_AST(node) ? []];
- */
- for (ni = 1; ni <= 4; ni++) {
- anode = (Node)0;
- if (ni == 1 && N_AST1_DEFINED(nkind)) anode =N_AST1(node);
- else if (ni == 2 && N_AST2_DEFINED(nkind)) anode = N_AST2(node);
- else if (ni == 3 && N_AST3_DEFINED(nkind)) anode = N_AST3(node);
- else if (ni == 4 && N_AST4_DEFINED(nkind)) {
- anode = N_AST4(node);
- if (N_KIND(anode) == as_instance_tuple) continue;
- /* treated above as special case in instance nodes */
- }
- if (anode == (Node)0) continue;
- nnode = instantiate_tree(anode, rename_map);
- if (anode != (Node)0) {
- if (ni == 1) N_AST1(root) = nnode;
- else if (ni == 2) N_AST2(root) = nnode;
- else if (ni == 3) N_AST3(root) = nnode;
- else if (ni == 4) N_AST4(root) = nnode;
- }
- }
- if (N_LIST_DEFINED(nkind))
- ltup = N_LIST(node);
- else
- ltup = (Tuple)0;
- if (ltup != (Tuple)0) {
- /* N_LIST(root) := [instantiate_tree(n, rename_map):
- * n in N_LIST(node) ? []];
- */
- n = tup_size(ltup);
- ntup = tup_new(n);
- FORTUPI(nnode=(Node), ltup, i, ft1);
- ntup[i] = (char *)instantiate_tree(nnode, rename_map);
- ENDFORTUP(ft1);
- N_LIST(root) = ntup;
- }
- /*
- * In the case of a slice, the procedure slice_type reformats the as_slice node.
- * The lower and upper bounds nodes of the as_range are incorporated into
- * an anonymous subtype (slice_index_type). The N_AST2 of the as_slice node
- * points to a new name node with this slice_index_type as its N_UNQ. As a
- * conseqeunce of this reformatting the bounds nodes are no longer connected
- * to the tree rooted by the as_slice node and are left out when tranversing
- * the tree in instantiate_tree. Threfore, a special check is made in this
- * case to instantiate the bound nodes as well.
- */
- if ((nkind == as_slice) && (N_KIND(N_AST2(node)) == as_simple_name)) {
- tup = SIGNATURE(N_UNQ(N_AST2(node)));
- nnode = instantiate_tree((Node)numeric_constraint_low(tup),rename_map);
- nnode = instantiate_tree((Node)numeric_constraint_high(tup),rename_map);
- }
- nodemap_put(node_map, node, root);
- return root;
- }
-
- static int check_recursive_instance(Node node) /*;check_recursive_instance*/
- {
- /* Verify that an instance appearing in the current instantiation does
- * not include an instantiation of the unit being instantiated. we
- * use current_instances to keep track of units already seen.
- */
-
- Node specs_node, priv_node, body_node;
- Node gen_node;
- Symbol nam;
- int nat;
- Tuple sig;
- Node body;
-
- gen_node = N_AST2(node);
- nam = N_UNQ(gen_node);
- if (tup_memsym(nam, current_instances)) {
- errmsg("Invalid recursive instantiation", "12.3", current_node);
- return TRUE;
- }
- else {
- current_instances = tup_with(current_instances, (char *) nam );
- nat = NATURE(nam);
- if (nat == na_generic_procedure || nat == na_generic_function) {
- sig = SIGNATURE(nam);
- body = (Node) sig[3];
- if (scan_instance(body)) return TRUE;
- }
- else if (nat == na_generic_package_spec) {
- sig = SIGNATURE(nam);
- specs_node = (Node)sig[2];
- priv_node = (Node) sig[3];
- if (scan_instance(specs_node)) return TRUE;
- if (scan_instance(priv_node)) return TRUE;
- }
- else if (nat == na_generic_package) {
- sig = SIGNATURE(nam);
- specs_node = (Node) sig[2];
- priv_node = (Node) sig[3];
- body_node = (Node) sig[4];
- if (scan_instance(specs_node)) return TRUE;
- if (scan_instance(priv_node)) return TRUE;
- if (scan_instance(body_node)) return TRUE;
- }
- nam = (Symbol) tup_frome(current_instances );
- }
- return FALSE;
- }
-
- static int scan_instance(Node node) /*;scan_instance */
- {
- /* Subsidiary procedure to the above: search the specs or body of a
- * generic object, for the presence of forward instantiations, i.e.
- * instantiations that preceded the body of the generic. Non-trivial
- * recursive instantiations can only occur in the presence of such.
- */
-
- int i, nkind;
- Fortup ft1;
- Node inode;
-
- if ( N_KIND(node) == as_function_instance
- || N_KIND(node) == as_procedure_instance
- || N_KIND(node) == as_package_instance)
- if (check_recursive_instance(node)) return TRUE;
- else {
- nkind = N_KIND(node);
- for (i = 1; i <= 4; i++) {
- inode = (Node)0;
- if (i == 1 && N_AST1_DEFINED(nkind)) inode = N_AST1(node);
- else if (i == 2 && N_AST2_DEFINED(nkind)) inode = N_AST2(node);
- else if (i == 3 && N_AST3_DEFINED(nkind)) inode = N_AST3(node);
- else if (i == 4 && N_AST4_DEFINED(nkind)) inode = N_AST4(node);
- if (inode != (Node)0)
- if (scan_instance(inode)) return TRUE;
- }
- if (N_LIST_DEFINED(nkind) && N_LIST(node) != (Tuple)0) {
- FORTUP(inode=(Node), N_LIST(node), ft1);
- if (scan_instance(inode)) return TRUE;
- ENDFORTUP(ft1);
- }
- }
- return FALSE;
- }
-
- Symbol replace(Symbol expn, Symbolmap mapping) /*;replace*/
- {
- Symbol sym;
-
- if (cdebug2 > 3) TO_ERRFILE("AT PROC : replace");
-
- sym = symbolmap_get(mapping, expn);
- if (sym != (Symbol)0)
- return sym;
- else return expn;
- }
-
- Symbolmap symbolmap_new() /*;symbolmap_new*/
- {
- /* initialize symbolmap for n entries */
-
- Symbolmap smap;
-
- smap = (Symbolmap) emalloct(sizeof(struct Symbolmap_s), "symbolmap-new");
- smap->symbolmap_tuple = tup_new(0);
- return smap;
- }
-
- Symbol symbolmap_get(Symbolmap type_map, Symbol sym) /*;symbolmap_get*/
- {
- int i, n;
- Tuple tup;
-
- tup = type_map->symbolmap_tuple;
- n = tup_size(tup);
- for (i = 1; i <= n; i+=2)
- if (tup[i] == (char *)sym)
- return (Symbol) tup[i+1];
- /* symbolmap_get returns (Symbol)0 if map undefined */
- return (Symbol) 0;
- }
-
- void symbolmap_put(Symbolmap type_map, Symbol symd, Symbol symv)
- /*;symbolmap_put*/
- {
- int i, n;
- Tuple tup;
-
- tup = type_map->symbolmap_tuple;
- n = tup_size(tup);
- for (i = 1; i <= n; i+=2) {
- if (tup[i] == (char *)symd) {
- tup[i+1] = (char *)symv;
- return;
- }
- }
- /* here if need to extend map. */
- tup = tup_exp(tup, (unsigned) (n+2));
- type_map->symbolmap_tuple = tup;
- tup[n+1] = (char *)symd;
- tup[n+2] = (char *)symv;
- return;
- }
-
- Nodemap nodemap_new() /*;nodemap_new*/
- {
- /* initialize nodemap for n entries */
-
- Nodemap nmap;
-
- nmap = (Nodemap) emalloct(sizeof(struct Nodemap_s), "nodemap-new");
- nmap->nodemap_tuple = tup_new(0);
- return nmap;
- }
-
- static void nodemap_free(Nodemap smap) /*;nodemap_free*/
- {
- tup_free(smap->nodemap_tuple);
- efreet((char *) smap, "node-map-free");
- }
-
- static Node nodemap_get(Nodemap node_map, Node sym) /*;nodemap_get*/
- {
- int i, n;
- Tuple tup;
-
- tup = node_map->nodemap_tuple;
- n = tup_size(tup);
- for (i = 1; i <= n; i+=2)
- if (tup[i] == (char *)sym)
- return (Node) tup[i+1];
- return (Node)0;
- }
-
- static void nodemap_put(Nodemap node_map, Node symd, Node symv) /*;nodemap_put*/
- {
- int i, n;
- Tuple tup;
-
- tup = node_map->nodemap_tuple;
- n = tup_size(tup);
- for (i = 1; i <= n; i+=2) {
- if (tup[i] == (char *)symd) {
- tup[i+1] = (char *)symv;
- return;
- }
- }
- /* here if need to extend map. */
- tup = tup_exp(tup, (unsigned) n+2);
- node_map->nodemap_tuple = tup;
- tup[n+1] = (char *)symd;
- tup[n+2] = (char *)symv;
- return;
- }
-